package com.atguigu.juc;


import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

class MyCache{
    Map<String ,String> map = new HashMap<>();

  /*  Lock lock = new ReentrantLock(  );
    public void write(String key,String value){
        Lock.lock();

        try{
            System.out.println(Thread.currentThread().getName()+"\t"+"----准备写入");
            String result = map.put( key, value );
            System.out.println(Thread.currentThread().getName()+"\t"+"----完成写入+");
        }finally {
            Lock.unlock();
        }
    }
    public void read(String key)
    {
        lock.lock();
        try
        {
            System.out.println(Thread.currentThread().getName()+"\t"+"---准备读取");
            String s = map.get(key);
            System.out.println(Thread.currentThread().getName()+"\t"+"---完成读取 "+s);
        }finally {
            lock.unlock();
        }
    }*/

    final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    public void write(String key,String value)
    {
        rwl.writeLock().lock();
        try
        {
            System.out.println(Thread.currentThread().getName()+"\t"+"---准备写入");
            String result = map.put(key, value);
            try { TimeUnit.MILLISECONDS.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); }
            System.out.println(Thread.currentThread().getName()+"\t"+"---完成写入 "+result);
        }finally {
            rwl.writeLock().unlock();
        }
    }

    public void read(String key) {
        rwl.readLock().lock();
        try {
            System.out.println( Thread.currentThread().getName() + "\t" + "---准备读取" );
            String s = map.get( key );
            System.out.println( Thread.currentThread().getName() + "\t" + "---完成读取 " + s );
        } finally {
            rwl.readLock().unlock();
        }
    }
}

/**
 * @auther zzyy
 * @create 2021-09-03 9:32
 * 读写锁
 *
 * 对于同一个资源，我们涉及多线程的操作，有读，有写，交替进行。
 * 为了保证读写的数据一致性,场景：读多写少+读写分离
 *
 * 读 读 可共享
 * 读 写 不共享
 * 写 写 不共享
 * 读的时候希望高并发同时进行，可以共享，可以多个线程同时操作进行中.....
 * 写的时候为了保证数据一致性，需要独占排它。
 *
 *
 * 题目：5个线程读，5个线程写入，操作同一个资源
 */

public class ReadWriteLockDemo
{
    public static void main(String[] args)
    {
        MyCache myCache = new MyCache();

        for (int i = 1; i <=10; i++) {
            int finalI = i;
            new Thread(() -> {
                myCache.write(finalI +"", finalI +"");
            },String.valueOf(i)).start();
        }

        //暂停毫秒
        try { TimeUnit.MILLISECONDS.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); }

        for (int i = 1; i <=10; i++) {
            int finalI = i;
            new Thread(() -> {
                myCache.read(finalI +"");
            },String.valueOf(i)).start();
        }
    }
}
